package com.kaiwukj.android.ufamily.mvp.ui.page.mine.house.door;

import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.blankj.utilcode.util.LogUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.kaiwukj.android.ufamily.BuildConfig;
import com.kaiwukj.android.ufamily.R;
import com.kaiwukj.android.ufamily.app.base.review.BaseActivity;
import com.kaiwukj.android.ufamily.app.constant.ARouterUrlKt;
import com.kaiwukj.android.ufamily.app.constant.EventCode;
import com.kaiwukj.android.ufamily.mvp.http.entity.event.KaiwuEvent;
import com.kaiwukj.android.ufamily.utils.CallHintUtil;
import com.kaiwukj.android.ufamily.utils.VibratorUtil;
import com.zghl.mclient.client.ZghlMClient;
import com.zghl.mclient.client.ZghlPhoneClient;
import com.zghl.mclient.client.ZghlPhoneListener;
import com.zghl.mclient.client.beans.CallUpInfo;
import com.zghl.mclient.client.utils.LogUtil;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.linphone.core.LinphoneCall;
import org.linphone.core.Reason;
import org.linphone.zgphone.CallStatsAvtivity;

import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;

@Route(path = ARouterUrlKt.ZghlVideoUrl)
public class ZghlVideoActivity extends BaseActivity {

    @BindView(R.id.text_door_name)
    TextView tvDoorName;
    @BindView(R.id.text_area_name)
    TextView tvAreaName;
    @BindView(R.id.layout_video)
    RelativeLayout containerVideo;
    @BindView(R.id.video_surface)
    LinearLayout videoSurface;
    @BindView(R.id.img_photo)
    ImageView imgPhoto;
    @BindView(R.id.text_photo_hint)
    TextView tvPhotoHint;
    @BindView(R.id.text_state)
    TextView tvState;
    @BindView(R.id.text_left)
    TextView tvLeft;
    @BindView(R.id.layout_open_door)
    ViewGroup containerOpenDoor;
    @BindView(R.id.text_right)
    TextView tvRight;
    @BindView(R.id.img_shake)
    ImageView mImgShake;

    private ZghlVideoActivity instance;

    private String mDoorName;
    private String mAreaName;
    private String username;

    private String callSip;

    private AlertDialog hangUpDialog;
    private AlertDialog openDoorDialog;

    private String image;
    private long first;
    private long temp;

    private String guid;
    private boolean isOpen;
    private boolean clickBtn;
    private boolean isEngaged;

    @OnClick(R.id.layout_open_door)
    void openDoorClick() {
        // 统一开门方式
        ZghlMClient.getInstance().openDoor(guid);
        clickBtn = true;
        startOpenDoorTimer();
        // 防止点击多次，5秒内不可点
        containerOpenDoor.setEnabled(false);
        subscribe(Observable.timer(5000, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    if (containerOpenDoor != null) {
                        containerOpenDoor.setEnabled(true);
                    }
                }));
        startShakeByPropertyAnim(mImgShake);
    }

    @OnClick(R.id.text_left)
    void onLeftClick() {
        if (isEngaged) {
            //接听中，直接挂断
            if (timer != null) {
                timer.cancel();
            }
            ZghlPhoneClient.getInstance().hangUp();
        } else {
            //  非接听状态，转发 MQTT挂断，
            ZghlMClient.getInstance().hangUp(guid);
            onBackPressedSupport();
        }
    }

    @OnClick(R.id.text_right)
    void onRightClick() {
        if (isEngaged) {
            //接听中，点击切换 听筒及扬声器
            toggleSpeaker();
        } else {
            tvRight.setEnabled(false);
            //非接听状态，接听(实际为拨打电话)，并改变界面视图
            //DialogProgress.showDialog(this);
            showLoading("正在请求");
            ZghlPhoneClient.getInstance().newOutgoingCall(this, callSip);
            CallHintUtil.stopInComingHint(instance);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onEventMainThread(KaiwuEvent bean) {
        switch (bean.getCode()) {
            case EventCode.EVENT_OPEN_DOOR:
                if (!clickBtn) {
                    return;
                }
                isOpen = true;
                VibratorUtil.vibrate(mContext, 200);
                showOpenDoorDialog(true);
                if (openDoorTimer != null) {
                    openDoorTimer.cancel();
                }
                clickBtn = false;
                break;
            case EventCode.EVENT_HANG_UP:
                // 门禁机挂断（弹窗）
                showHangUpDialog("呼叫结束", "对方已挂断");
                break;
            default:
                break;
        }
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_phone;
    }

    @Override
    protected void initView(Bundle savedInstanceState) {
        instance = this;
        tvDoorName.setOnClickListener(v -> {
            if (BuildConfig.DEBUG) {
                startActivity(new Intent(this, CallStatsAvtivity.class));
            }
        });
    }

    @Override
    protected void initData(Bundle savedInstanceState) {

        getDefData();

        tvDoorName.setText(mDoorName);
        tvAreaName.setText(mAreaName);

        ZghlPhoneClient.getInstance().addPhoneListener(this, username, new ZghlPhoneListener() {
            @Override
            public void callState(LinphoneCall call, LinphoneCall.State state, String message) {

                LogUtils.d("state----------------->" + state + "---" + call.getErrorInfo().getReason().toString() + "---" + message);
                if (LinphoneCall.State.Connected == state) {
                    loadCount = 11;
                    startAnswer();
                    //DialogProgress.dismissDialog();
                    hideLoading();
                } else if (state == LinphoneCall.State.StreamsRunning) {
                    tvPhotoHint.setVisibility(View.INVISIBLE);
                    imgPhoto.setVisibility(View.INVISIBLE);
                    //DialogProgress.dismissDialog();
                    hideLoading();
                } else if (state == LinphoneCall.State.Error) {
                    //DialogProgress.dismissDialog();
                    hideLoading();
                    LogUtils.d("callState: " + state.toString() + "   " + call.getErrorInfo().getReason());
                    if (call.getErrorInfo().getReason() == Reason.Busy) {
                        showHangUpDialog("呼叫结束", "此次呼叫已被接听");
                    } else {
                        showHangUpDialog("呼叫异常", "暂时无法接通");
                    }
                } else if (state == LinphoneCall.State.CallEnd) {
                    // ZGPhoneManager2
                    //DialogProgress.dismissDialog();
                    hideLoading();
                    subscribe(Observable.timer(500, TimeUnit.MILLISECONDS)
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(aLong -> finish()));
                }
            }
        });

        CallHintUtil.callInComing(this);

        //initSound();
    }

    private void getDefData() {
        CallUpInfo callUpInfo = ZghlMClient.getInstance().getCallUpInfo();
        guid = callUpInfo.getGuid();
        username = callUpInfo.getMySip();
        image = callUpInfo.getImgUrl();
        callSip = callUpInfo.getCallSip();
        mDoorName = callUpInfo.getName();
        mAreaName = callUpInfo.getCommunity();

        LogUtils.d("imageUrl---------------------------->" + image);

        LogUtil.e("PhoneActivity", "username: " + username + "   callphone:" + callUpInfo.getCallSip());
        if (!TextUtils.isEmpty(image)) {
            LogUtil.e("image", image);
            first = System.currentTimeMillis();
            temp = first;
            loadPhoto(image);
            startLoadPhotoTimer();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        ZghlPhoneClient.getInstance().onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        CallHintUtil.stopInComingHint(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (timer != null) {
            timer.cancel();
        }
        ZghlPhoneClient.getInstance().onDestroy();
        CallHintUtil.stopInComingHint(this);

        if (openDoorTimer != null) {
            openDoorTimer.cancel();
        }
        if (loadPhotoTimer != null) {
            loadPhotoTimer.cancel();
        }

        if (hangUpDialog != null && hangUpDialog.isShowing()) {
            hangUpDialog.dismiss();
        }
        if (openDoorDialog != null && openDoorDialog.isShowing()) {
            openDoorDialog.dismiss();
        }
        if (alertDialog != null && alertDialog.isShowing()) {
            alertDialog.dismiss();
        }
    }

    private boolean isSpeakerEnabled = false;

    public void startAnswer() {
        isSpeakerEnabled = true;
        changeUIandState();
        startTime();
        ZghlPhoneClient.getInstance().startSurfaceVideo(this, R.id.video_surface);
    }

    public void setSpeakerEnabled(boolean enabled) {
        if (enabled) {
            tvRight.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.video_mianti_0_icon, 0, 0);
        } else {
            tvRight.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.video_mianti_1_icon, 0, 0);
        }
    }

    private void changeUIandState() {
        subscribe(Observable.timer(100, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    tvLeft.setText(getResources().getText(R.string.hang_up));
                    tvRight.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.video_mianti_0_icon, 0, 0);
                    tvRight.setText("免提");
                    tvRight.setEnabled(true);
                }));

        isEngaged = true;
    }

    protected void toggleSpeaker() {
        LogUtil.e("isSpeaker", isSpeakerEnabled + "");
        isSpeakerEnabled = !isSpeakerEnabled;
        ZghlPhoneClient.getInstance().toggleSpeaker(isSpeakerEnabled);
        setSpeakerEnabled(isSpeakerEnabled);
    }

    private int loadCount;

    private void loadPhoto(final String imgUrl) {
        if (loadCount < 11 && imgPhoto != null) {
            if (!instance.isFinishing()) {
                LogUtil.e("imgUrl------------------->", imgUrl + "&_t=" + first);
                Glide.with(mContext)
                        .load(imgUrl + "&_t=" + first)
                        .placeholder(getResources().getDrawable(R.drawable.menjing_jiazai_icon))
                        .addListener(new RequestListener<Drawable>() {
                            @Override
                            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                                LogUtils.e("onLoadFailed: " + loadCount);
                                first = System.currentTimeMillis();
                                new Handler().post(() -> loadPhoto(image));
                                return false;
                            }

                            @Override
                            public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                                LogUtils.e("onResourceReady: " + (first - temp));
                                return false;
                            }
                        }).into(imgPhoto);
            }
        }
    }

    private CountDownTimer timer;

    private void startTime() {
        tvState.setVisibility(View.VISIBLE);
        //每隔countDownInterval秒会回调一次onTick()方法
        timer = new CountDownTimer(56 * 1000, 1000) {
            private long time;

            @Override
            public void onTick(long millisUntilFinished) {
                //每隔countDownInterval秒会回调一次onTick()方法
                time = millisUntilFinished / 1000;
                String head = "00:";

                if (time > 10) {
                    if ((56 - time) < 10) {
                        head = "00:0";
                    } else {
                        head = "00:";
                    }
                    if (tvState != null) {
                        tvState.setText(head + (56 - time));
                    }
                } else {
                    if (tvState != null) {
                        tvState.setText(time + "s后自动挂断");
                    }
                }
            }

            @Override
            public void onFinish() {
                if (instance != null && !instance.isFinishing()) {
                    ZghlPhoneClient.getInstance().hangUp();
                    finish();
                }
            }
        };
        timer.start();// 开始计时
    }

    private CountDownTimer loadPhotoTimer;

    private void startLoadPhotoTimer() {
        //每隔countDownInterval秒会回调一次onTick()方法
        loadPhotoTimer = new CountDownTimer(12 * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                loadCount++;
            }

            @Override
            public void onFinish() {
            }
        };
        loadPhotoTimer.start();// 开始计时
    }

    private CountDownTimer openDoorTimer;

    private void startOpenDoorTimer() {
        //每隔countDownInterval秒会回调一次onTick()方法
        openDoorTimer = new CountDownTimer(6 * 1000, 1000) {

            @Override
            public void onTick(long millisUntilFinished) {
                LogUtil.e("startOpenDoorTimer", millisUntilFinished / 1000 + "");
                if (isOpen && openDoorTimer != null) {
                    openDoorTimer.cancel();
                    isOpen = false;
                }
            }

            @Override
            public void onFinish() {
                LogUtil.e("startOpenDoorTimer onFinish", isOpen + "   " + isEngaged);

                if (!isOpen) {
                    if (isEngaged) {
                        // 接听中，开门失败，弹出密码弹窗
                        showOpenDoorPWDDialog();
                    } else {
                        // 未接通 开门失败 普通弹窗
                        showOpenDoorDialog(false);
                    }
                }
                isOpen = false;
            }
        };
        openDoorTimer.start();// 开始计时
    }

    private void showHangUpDialog(String titleInfo, String msgInfo) {
        if (hangUpDialog != null) {
            return;
        }
        final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.MyDialogStyle);
        final View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_phone_cannot, null);
        hangUpDialog = builder.setView(dialogView).create();
        hangUpDialog.setCanceledOnTouchOutside(false);
        TextView title = dialogView.findViewById(R.id.text_title);
        title.setText(msgInfo);
        hangUpDialog.show();

        subscribe(Observable.timer(3000, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    if (instance != null && !instance.isFinishing()) {
                        if (hangUpDialog != null && hangUpDialog.isShowing()) {
                            hangUpDialog.dismiss();
                            hangUpDialog = null;
                            finish();
                        }
                    }
                }));
    }

    private void showOpenDoorPWDDialog() {
        showOpenFailDialog();
        mImgShake.clearAnimation();
    }

    private void showOpenDoorDialog(boolean isOpen) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.MyDialogStyle);
        final View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_phone_open_door, null);
        openDoorDialog = builder.setView(dialogView).create();
        openDoorDialog.setCanceledOnTouchOutside(false);

        TextView msg = dialogView.findViewById(R.id.text_state);
        ImageView imageView = dialogView.findViewById(R.id.img_state);
        if (isOpen) {
            msg.setText("开门成功");
            imageView.setImageResource(R.drawable.kaomen_ok_icon);
            mImgShake.setImageResource(R.drawable.video_chenggon_icon_0);
            subscribe(Observable.timer(5000, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(aLong -> {
                        if (instance != null && !instance.isFinishing()) {
                            if (mImgShake != null) {
                                mImgShake.setImageResource(R.mipmap.ic_zghl_video_chat_open);
                            }
                        }
                    }));
        } else {
            msg.setText("开门失败");
            imageView.setImageResource(R.drawable.kaomen_no_icon);
        }
        openDoorDialog.show();
        mImgShake.clearAnimation();

        subscribe(Observable.timer(2000, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    if (instance != null && !instance.isFinishing()) {
                        if (openDoorDialog != null) {
                            openDoorDialog.dismiss();
                        }
                    }
                }));

    }

    private void startShakeByPropertyAnim(View view) {
        if (view == null) {
            return;
        }
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
        view.startAnimation(animation);
    }

    private AlertDialog alertDialog;

    public void showOpenFailDialog() {

        if (alertDialog == null) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.MyDialogStyle);
            final View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_open_fail, null);
            alertDialog = builder.setView(dialogView).create();
            alertDialog.setCanceledOnTouchOutside(false);

            TextView msg = dialogView.findViewById(R.id.text_msg);
//            String regex = "(.{1})";

            String totpToken = ZghlMClient.getInstance().getDoorPassword();

            msg.setText(totpToken/*.replaceAll(regex, "$1 ")*/);
            dialogView.findViewById(R.id.text_btn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (alertDialog != null) {
                        alertDialog.dismiss();
                    }
                }
            });
            alertDialog.show();
        } else if (!alertDialog.isShowing()) {
            alertDialog.show();
        }
    }
}
